#!/usr/bin/env bash

##
# Author: Yuri Karadzhov <yuri.karadzhov@gmail.com>
##

## usage string
USAGE="Usage: $0 [-a] [-c] [-u] [-h] \n\n
       -a Autoinstall new kernel if avalible \n
       -u Update kernel with upcomming releases \n\n
       -h This prompt \n"

## cleaning procedure
function clean {
  cd /
  echo 'Cleaning...'
  rm -rf /tmp/KERNEL_UPD
}

clean

## ubuntu release codename
RELEASE_CDN=`lsb_release -cs`

## autoinstall key
AUTO=0

## notification commands
KNOTIFY=`which kdialog`
NOTIFY=`which notify-send`

## release value
RELEASE=$RELEASE_CDN

## installed kernel version
KERNEL_V='v'`uname -r`

## kernel repository
REP='http://kernel.ubuntu.com/~kernel-ppa/mainline'

## check root privileges
if [ `whoami` != 'root' ]; then
  echo "Permission denied. Run $0 as the root"
  exit 1;
fi

## get system architecture
if [ `uname -m` == 'x86_64' ]; then
  ARCH='amd64'
else
  ARCH="i386"
fi

## options check and parse
while getopts ":auh" opt; do
  case "$opt" in
    "a") AUTO=1;;
    "u") RELEASE='';;
    "h")
      echo -e $USAGE
      exit 0;;
    "?")
      echo "Invalid option $OPTARG. Try $0 -h for help"
      exit 1;;
    *)
      echo "Unknown error while processing options"
      exit 1;;
  esac
done

## get the last avalible kernel version
KERNEL_A=`wget -qO - $REP | egrep -o "v[0-9]\.[0-9][\.]?[0-9]?-$RELEASE\w*/" | tail -n 1`

## major kernel versions
KERNEL_C=`echo $KERNEL_V | grep -o "v[0-9]\.[0-9].[0-9]*" | head -n 1`
KERNEL_N=`echo $KERNEL_A | grep -o "v[0-9]\.[0-9].[0-9]*" | head -n 1`

## if new version avalible -- install it
if [[ $KERNEL_N>$KERNEL_C ]]; then

  if [ $AUTO -eq 0 ]; then
    read -p "You are going to install kernel $KERNEL_A for $ARCH. Do you want to continue (y/n)?" REPLY
  else
    REPLY='y'
  fi

  if [ $REPLY == 'y' ]; then

    ## create installation directory
    mkdir /tmp/KERNEL_UPD
    cd /tmp/KERNEL_UPD

    ## get kernel links
    KERNEL_LIST=`wget -qO - $REP/$KERNEL_A`
    HEADERS_ALL=`echo $KERNEL_LIST | grep -o "linux-headers-[^>]*_all\.deb" | tail -n 1`
    HEADERS_ARCH=`echo $KERNEL_LIST | grep -o "linux-headers-[^>]*_"$ARCH"\.deb" | tail -n 1`
    IMAGE=`echo $KERNEL_LIST | grep -o "linux-image-[^>]*_"$ARCH"\.deb" | head -n 1`
    EXTRA=`echo $KERNEL_LIST | grep -o "linux-image-[^>]*_"$ARCH"\.deb" | tail -n 1`

    ## check kernel links and download the kernel
    if [ $HEADERS_ALL -a $HEADERS_ARCH -a $IMAGE -a $EXTRA ]; then
      echo "Uploading kernel $KERNEL_A"
      wget $REP/$KERNEL_A/$HEADERS_ALL $REP/$KERNEL_A/$HEADERS_ARCH $REP/$KERNEL_A/$IMAGE $REP/$KERNEL_A/$EXTRA
      if [ $? -eq 0 ]; then

        ## kernel install
        dpkg -i *.deb
        if [ $? -eq 0 ]; then
          clean
          echo "Kernel $KERNEL_A was succesfuly installed"
          echo "Please, reboot your computer for the changes to take effect"
          /usr/share/update-notifier/notify-reboot-required
          if [ $AUTO -eq 0 ]; then
            read -p 'Do you want to reboot computer now (y/n)?' REPLY
            if [ $REPLY == 'y' ]; then
              shutdown -r 0
            fi
          else
            if [[ -n $NOTIFY ]]; then
              notify-send 'Installation finished' "Kernel $KERNEL_A was succesfuly installed<br>
                                                   Please, reboot your computer for the changes to take effect"
            elif [[ -n $KNOTIFY ]]; then
              kdialog --title 'Installation finished' --passivepopup "Kernel $KERNEL_A was succesfuly installed<br>
                                                                      Please, reboot your computer for the changes to take effect"
            fi
          fi
          exit 0;
        else
          echo "Error while installing kernel $KERNEL_A"
          clean
          exit 1;
        fi
      else
        echo 'Error while uploading kernel'
        clean
        exit 1;
      fi
    else
      echo "Error on server - $REP/$KERNEL_A contains incomplete kernel"
      clean
      exit 1;
    fi
  else
    echo 'User interrupts installation'
    exit 0;
  fi
else
  echo "Your kernel is up to date"
  exit 0;
fi
